package org.luxor.storage.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.luxor.commons.core.utils.AssertUtils;
import org.luxor.commons.core.web.controller.BaseRestController;
import org.luxor.commons.core.web.data.R;
import org.luxor.commons.storage.constant.StorageType;
import org.luxor.commons.storage.service.IFileStorageService;
import org.luxor.storage.constant.OssConstant;
import org.luxor.storage.entity.OssConfigEntity;
import org.luxor.storage.entity.OssFileEntity;
import org.luxor.storage.service.IOssConfigService;
import org.luxor.storage.service.impl.OssFileMgrServiceImpl;
import org.luxor.storage.utils.ParamExtUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * OSS文件上传与下载
 *
 * @author Mr.yan @date 2020/3/11
 */
@Controller
@RequestMapping(OssConstant.SSO_PATH_MARK)
@Api(tags = "OSS上传与下载")
public class OssController extends BaseRestController {
    private static final Logger logger = LoggerFactory.getLogger(OssController.class);

    @Resource
    private OssFileMgrServiceImpl ossFileMgrService;
    @Resource
    private IFileStorageService fileStorageService;
    @Resource
    private IOssConfigService ossConfigService;

    @ApiOperation("OSS上传文件")
    @PreAuthorize("isAuthenticated()")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storageType", value = "存储类型(1：本地磁盘 2：FastDfs 3：七牛  4：阿里云  5：腾讯云)"
                    , paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "file", value = "MultipartFile文件", paramType = "body", required = true)
    })
    @PostMapping("/upload")
    public R upload(@RequestParam(required = false) Integer storageType,
                                 @RequestParam("file") MultipartFile file) throws IOException {
        if (storageType == null) {
            OssConfigEntity storageTypeConfig = ossConfigService.getByConfigKey(OssConstant.STORAGE_TYPE_KEY);
            if (storageTypeConfig != null) {
                String val = storageTypeConfig.getConfigValue();
                if (val != null) {
                    storageType = Integer.parseInt(val);
                }
            }
        }
        AssertUtils.notNull(storageType, "必须指定OSS存储类型，storageType不能为空！");

        OssFileEntity ossFileEntity = ossFileMgrService.upload(StorageType.valueOf(storageType), file);
        logger.info("上传成功. ossFile:{}", ossFileEntity);
        return R.ok(ossFileEntity);
    }

    @GetMapping("/**")
    @ApiOperation("OSS普通文件下载")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "fileFullPath", value = "文件存储目录(/sso/images/2020-03-23/background_1_000939920.jpg)"
                    , paramType = "path", dataType = "String", required = true),
            @ApiImplicitParam(name = "token", value = "防盗链Token", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "ts", value = "防盗链Token生成时间", paramType = "query", dataType = "Long")
    })
    public void httpDownload(@RequestParam(required = false) String token, @RequestParam(required = false) Long ts
            , HttpServletRequest request, HttpServletResponse response) {
        String fileFullPath = ParamExtUtils.extFileFullPath(request.getServletPath());
        Integer storageType = ParamExtUtils.extStorageType(fileFullPath);
        String fileFullName = ParamExtUtils.extFileFullName(fileFullPath);
        String mimeType = ParamExtUtils.getMimeType(fileFullName);
        if (MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE.equals(mimeType)) {
            response.addHeader("Content-Disposition", "attachment; filename=\"" + fileFullName + "\"");
        }
        response.addHeader("Content-Type", mimeType);
        fileStorageService.antiStealHttpDownload(StorageType.valueOf(storageType), fileFullPath, token, ts, response);
    }

}
